package com.ccteam.fluidmusic.ui.auth

import android.app.Application
import androidx.lifecycle.*
import androidx.work.*
import com.ccteam.fluidmusic.utils.Event
import com.ccteam.fluidmusic.utils.cancelIfActive
import com.ccteam.fluidmusic.utils.preference.SettingWorker
import com.ccteam.fluidmusic.view.bean.ErrorMessage
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.model.Resource
import com.ccteam.model.user.UserLoginDTO
import com.ccteam.shared.core.UserCore
import com.ccteam.shared.domain.auth.LoginDataUseCase
import com.ccteam.shared.domain.auth.VerificationDataUseCase
import com.orhanobut.logger.Logger
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/3/29
 *
 * 通过验证码登录ViewModel
 */
@HiltViewModel
class LoginVerificationViewModel @Inject constructor(
    application: Application,
    private val userCore: UserCore,
    private val loginDataUseCase: LoginDataUseCase,
    private val verificationDataUseCase: VerificationDataUseCase,
    private val oneTimeWorkRequest: OneTimeWorkRequest,
    private val periodicWorkRequest: PeriodicWorkRequest
): AndroidViewModel(application) {

    private val _isLogin = MutableLiveData(false)
    val isLogin: LiveData<Boolean> get() = _isLogin

    private val _loadMessage = MutableLiveData<Event<LoadMessage>>()
    val loadMessage: LiveData<Event<LoadMessage>> get() = _loadMessage

    /**
     * 是否开启获取验证码按钮
     * 与 Timer 倒计时共同作用验证码开关
     */
    private val _enableVerifyCodeButton = MutableLiveData(false)
    val enableVerifyCodeButton: LiveData<Boolean> get() = _enableVerifyCodeButton

    /**
     * 是否开启倒计时计数
     */
    private val _enableCountDown = MutableLiveData(Event(false))
    val enableCountDown: LiveData<Event<Boolean>> get() = _enableCountDown

    private val phoneLiveData = MutableLiveData<String>()

    private var verifySuccess = MutableLiveData(false)
    private var phoneSuccess = MutableLiveData(false)

    private val _enableLoginButton = MediatorLiveData<Boolean>()
    val enableLoginButton: LiveData<Boolean> get() = _enableLoginButton

    private var loginJob: Job? = null
    init {
        loginJob = viewModelScope.launch {
            userCore.isLogin.collectLatest {
                _isLogin.value = it
            }
        }

        _enableLoginButton.addSource(verifySuccess){
            _enableLoginButton.value = it && phoneSuccess.value == true
        }
        _enableLoginButton.addSource(phoneSuccess){
            _enableLoginButton.value = it && verifySuccess.value == true
        }
    }

    fun getVerification(){
        if(_enableVerifyCodeButton.value == false){
            _loadMessage.value = Event(LoadMessage.Error(
                ErrorMessage(description = "无法进行此操作")
            ))
            return
        }

        viewModelScope.launch {
            val result = verificationDataUseCase(Pair(phoneLiveData.value,VerificationDataUseCase.LOGIN_CODE))

            if(result is Resource.Success){
                _enableCountDown.value = Event(true)
            } else {
                _loadMessage.value = Event(LoadMessage.Error(
                    ErrorMessage(result.message,result.errorCode)))
            }
        }

    }

    fun loginVerification(code: String){
        if(phoneLiveData.value.isNullOrEmpty() || code.isEmpty()){
            _loadMessage.value = Event(LoadMessage.Error(
                ErrorMessage(description = "账号或密码未输入")
            ))
            return
        }
        _loadMessage.value = Event(LoadMessage.Loading)
        viewModelScope.launch {
            val result = loginDataUseCase(UserLoginDTO(code,phoneLiveData.value!!,null))

            if(result is Resource.Success){
                // 将信息存储在DataStore中并更新
                result.data?.let {
                    Logger.d("登录成功:$result")
                    _loadMessage.value = Event(LoadMessage.NotLoading)
                    userCore.login(it.userId,it.tokenValue)
                    // 获取一次云端设置信息
                    WorkManager.getInstance(getApplication()).enqueueUniqueWork(
                        SettingWorker.SETTING_WORKER_ONCE_TAG,ExistingWorkPolicy.REPLACE,oneTimeWorkRequest
                    )
                    // 开启一个定期任务
                    WorkManager.getInstance(getApplication()).enqueueUniquePeriodicWork(
                        SettingWorker.SETTING_WORKER_TAG,ExistingPeriodicWorkPolicy.KEEP,periodicWorkRequest
                    )
                }
            } else {
                _loadMessage.value = Event(LoadMessage.Error(
                    ErrorMessage(result.message,result.errorCode)))
            }
        }
    }

    fun setEnableVerify(enable: Boolean){
        _enableVerifyCodeButton.value = enable
    }

    fun setVerifySuccess(success: Boolean){
        verifySuccess.value = success
    }

    fun setPhoneSuccess(success: Boolean){
        phoneSuccess.value = success
    }

    fun setPhone(phone: String){
        this.phoneLiveData.value = phone
    }

    override fun onCleared() {
        super.onCleared()

        loginJob.cancelIfActive()
    }
}